// RobotMotionPanel.js

class RobotMotionPanel {
    static instance = null;

    static initialize() {
        if (RobotMotionPanel.instance) {
            console.warn('RobotMotionPanel already initialized');
            return RobotMotionPanel.instance;
        }

        const maxAttempts = 10;
        let attempts = 0;

        const tryInitialize = () => {
            return new Promise((resolve, reject) => {
                const attempt = () => {
                    attempts++;
                    const container = document.getElementById('motion-control');

                    if (container) {
                        try {
                            RobotMotionPanel.instance = new RobotMotionPanel(container);
                            console.log('Motion control panel initialized');
                            resolve(RobotMotionPanel.instance);
                        } catch (error) {
                            reject(error);
                        }
                    } else if (attempts < maxAttempts) {
                        setTimeout(attempt, 100);
                    } else {
                        reject(new Error('Motion control panel container not found after multiple attempts'));
                    }
                };

                attempt();
            });
        };

        return tryInitialize();
    }

    static destroy() {
        if (RobotMotionPanel.instance) {
            RobotMotionPanel.instance.destroy();
            RobotMotionPanel.instance = null;
        }
    }

    constructor(container) {
        if (RobotMotionPanel.instance) {
            return RobotMotionPanel.instance;
        }

        this.container = container;
        this.stateManager = window.robotStateManager;

        this.state = {
            leftWheel: {
                speed: 0,
                enabled: false,
                encoderPulse: 0
            },
            rightWheel: {
                speed: 0,
                enabled: false,
                encoderPulse: 0
            },
            motion: {
                linearSpeed: 250,
                angularSpeed: 1500
            }
        };

        this.init();
    }

    renderUI() {
        this.container.innerHTML = `
            <div class="motion-panel">
                <!-- 参数设置区域 -->
                <div class="section-block">
                    <div class="module-title">运动控制</div>
                    <div class="params-grid">
                        <div class="param-item">
                            <label class="param-label">
                                <i data-lucide="move-horizontal"></i>
                                <span>线速度</span>
                            </label>
                            <input type="text" class="param-input" data-control="linearSpeed" value="50">
                            <span class="param-unit">mm/s</span>
                        </div>
                        <div class="param-item">
                            <label class="param-label">
                                <i data-lucide="rotate-ccw"></i>
                                <span>角速度</span>
                            </label>
                            <input type="text" class="param-input" data-control="angularSpeed" value="100">
                            <span class="param-unit">mrad/s</span>
                        </div>
                    </div>

                    <div class="wheel-params">
                        <div class="wheel-row">
                            <div class="param-item">
                                <label class="param-label">
                                    <i data-lucide="arrow-left"></i>
                                    <span>左轮速</span>
                                </label>
                                <input type="text" class="param-input" data-control="leftWheel" value="0">
                                <span class="param-unit">mm/s</span>
                            </div>
                            <div class="param-item">
                                <label class="param-label">
                                    <i data-lucide="arrow-right"></i>
                                    <span>右轮速</span>
                                </label>
                                <input type="text" class="param-input" data-control="rightWheel" value="0">
                                <span class="param-unit">mm/s</span>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- 控制区域 - 方向盘和编码器并排 -->
                <div class="control-area">
                    <div class="direction-pad">
                        <button class="direction-button forward" data-direction="forward">
                            <i data-lucide="arrow-up"></i>
                        </button>
                        <button class="direction-button backward" data-direction="backward">
                            <i data-lucide="arrow-down"></i>
                        </button>
                        <button class="direction-button left" data-direction="left">
                            <i data-lucide="arrow-left"></i>
                        </button>
                        <button class="direction-button right" data-direction="right">
                            <i data-lucide="arrow-right"></i>
                        </button>
                        <button class="stop-button">
                            <i data-lucide="square"></i>
                        </button>
                    </div>

                    <!-- 编码器状态 - 改为垂直排列 -->
                    <div class="encoder-column">
                        <div class="encoder-item">
                            <label class="encoder-label">
                                <i data-lucide="disc"></i>
                                <span>左轮脉冲</span>
                            </label>
                            <div class="encoder-value">0</div>
                        </div>
                        <div class="encoder-item">
                            <label class="encoder-label">
                                <i data-lucide="disc"></i>
                                <span>右轮脉冲</span>
                            </label>
                            <div class="encoder-value">0</div>
                        </div>
                        <div class="encoder-item">
                            <label class="encoder-label">
                                <i data-lucide="activity"></i>
                                <span>累计脉冲数</span>
                            </label>
                            <div class="encoder-value">0</div>
                        </div>
                    </div>
                </div>
            </div>
        `;

        lucide.createIcons();
    }

    // 发送运动控制指令
    sendMotionCommand(leftSpeed, rightSpeed) {
        const ws = window.webSocketHandler;
        if (!ws || !ws.isConnected) {
            console.error('WebSocket connection not available');
            return;
        }

        const proto = ws.protobufRoot.mstf.camb.proto;

        console.log("chassis motion control, left: ", leftSpeed, ", rihgt: ", rightSpeed);
        // 发送底盘控制指令
        ws.sendMessage("ChassisMiscGroup", "chass_misc", {
            info: {
                wheels: {
                    wheelLeft: {
                        val: { value: leftSpeed }
                    },
                    wheelRight: {
                        val: { value: rightSpeed }
                    }
                }
            }
        });
    }

    // 更新绑定事件，添加触摸支持
    bindEvents() {
        // 方向控制 - 同时支持鼠标和触摸
        const directionButtons = this.container.querySelectorAll('.direction-button');
        directionButtons.forEach(button => {
            // 鼠标事件
            button.addEventListener('mousedown', () => this.handleDirectionStart(button.dataset.direction));
            button.addEventListener('mouseup', () => this.handleStop());
            button.addEventListener('mouseleave', () => this.handleStop());

            // 触摸事件
            button.addEventListener('touchstart', (e) => {
                e.preventDefault();
                this.handleDirectionStart(button.dataset.direction);
            });
            button.addEventListener('touchend', (e) => {
                e.preventDefault();
                this.handleStop();
            });
            button.addEventListener('touchcancel', (e) => {
                e.preventDefault();
                this.handleStop();
            });
        });

        // 停止按钮
        const stopButton = this.container.querySelector('.stop-button');
        stopButton.addEventListener('click', () => this.handleStop());
        stopButton.addEventListener('touchstart', (e) => {
            e.preventDefault();
            this.handleStop();
        });

        // 参数输入处理
        const paramInputs = this.container.querySelectorAll('.param-input');
        paramInputs.forEach(input => {
            input.addEventListener('change', (e) => {
                const value = parseInt(e.target.value) || 0;
                const control = e.target.dataset.control;

                // 验证输入值范围
                let validatedValue = value;
                if (control === 'linearSpeed') {
                    validatedValue = Math.min(Math.max(value, 0), 500); // 限制线速度范围 0-500mm/s
                } else if (control === 'angularSpeed') {
                    validatedValue = Math.min(Math.max(value, 0), 3000); // 限制角速度范围 0-3000mrad/s
                }

                e.target.value = validatedValue;
                this.handleSpeedChange({
                    target: {
                        dataset: { control },
                        value: validatedValue
                    }
                });
            });

            // 添加输入限制
            input.addEventListener('input', (e) => {
                const value = e.target.value;
                if (!/^\d*$/.test(value)) {
                    e.target.value = value.replace(/\D/g, '');
                }
            });
        });
    }

    handleDirectionStart(direction) {
        const { linearSpeed, angularSpeed } = this.state.motion;
        let leftSpeed = 0;
        let rightSpeed = 0;

        switch (direction) {
            case 'forward':
                leftSpeed = rightSpeed = linearSpeed;
                break;
            case 'backward':
                leftSpeed = rightSpeed = -linearSpeed;
                break;
            case 'left':
                leftSpeed = -linearSpeed / 2;
                rightSpeed = linearSpeed / 2;
                break;
            case 'right':
                leftSpeed = linearSpeed / 2;
                rightSpeed = -linearSpeed / 2;
                break;
        }

        this.updateWheelSpeeds(leftSpeed, rightSpeed);
        // 发送运动指令
        this.sendMotionCommand(leftSpeed, rightSpeed);
    }

    handleStop() {
        this.updateWheelSpeeds(0, 0);
        // 发送停止指令
        this.sendMotionCommand(0, 0);
    }

    // 处理参数更新
    handleSpeedChange(event) {
        const control = event.target.dataset.control;
        const value = parseInt(event.target.value);

        if (control === 'linearSpeed' || control === 'angularSpeed') {
            this.state.motion[control] = value;
            this.stateManager.updateComponent(`motion.${control}`, value);
            this.updateSpeedDisplay(control, value);

            // 当参数更新时，如果机器人正在运动，更新当前运动状态
            if (this.isMoving()) {
                const { leftSpeed, rightSpeed } = this.calculateCurrentSpeeds();
                this.sendMotionCommand(leftSpeed, rightSpeed);
            }
        }
    }

    // 计算当前速度
    calculateCurrentSpeeds() {
        return {
            leftSpeed: this.state.leftWheel.speed,
            rightSpeed: this.state.rightWheel.speed
        };
    }

    // 检查是否正在运动
    isMoving() {
        return this.state.leftWheel.speed !== 0 || this.state.rightWheel.speed !== 0;
    }

    updateWheelSpeeds(leftSpeed, rightSpeed) {
        this.state.leftWheel.speed = leftSpeed;
        this.state.rightWheel.speed = rightSpeed;

        // 更新状态管理器
        this.stateManager.updateComponent('motion.wheels.left.speed', leftSpeed);
        this.stateManager.updateComponent('motion.wheels.right.speed', rightSpeed);

        // 更新显示
        this.updateSpeedDisplay('leftWheel', leftSpeed);
        this.updateSpeedDisplay('rightWheel', rightSpeed);
    }

    updateSpeedDisplay(type, value) {
        const displays = this.container.querySelectorAll('.speed-value');
        let display;

        switch (type) {
            case 'leftWheel':
                display = displays[0];
                break;
            case 'rightWheel':
                display = displays[1];
                break;
            case 'linearSpeed':
                display = displays[2];
                break;
            case 'angularSpeed':
                display = displays[3];
                break;
        }

        if (display) {
            const unit = type.includes('Speed') ? (type === 'angularSpeed' ? ' mrad/s' : ' mm/s') : ' mm/s';
            display.textContent = `${value}${unit}`;
        }
    }

    subscribeToStateChanges() {
        this.stateManager.addListener(state => {
            this.updateUI(state);
        });
    }

    // 更新 WebSocket 状态处理
    updateConnectionStatus(connected) {
        this.isConnected = connected;
        if (!connected) {
            this.handleStop(); // 断开连接时停止运动
        }
    }

    updateUI(state) {
        if (!state) return;

        // 更新轮子速度显示
        if (state.components?.motion?.wheels) {
            const { left, right } = state.components.motion.wheels;
            if (left) this.updateSpeedDisplay('leftWheel', left.speed || 0);
            if (right) this.updateSpeedDisplay('rightWheel', right.speed || 0);
        }

        // 更新运动参数显示
        if (state.components?.motion) {
            const { linearSpeed, angularSpeed } = state.components.motion;
            if (linearSpeed !== undefined) this.updateSpeedDisplay('linearSpeed', linearSpeed);
            if (angularSpeed !== undefined) this.updateSpeedDisplay('angularSpeed', angularSpeed);
        }

        // 更新编码器状态
        if (state.components?.motion?.encoders) {
            this.updateEncoderStatus(state.components.motion.encoders);
        }
    }

    updateEncoderStatus(status) {
        const leftEncoder = this.container.querySelector('.encoder-status .encoder-item:first-child .encoder-value');
        const rightEncoder = this.container.querySelector('.encoder-status .encoder-item:nth-child(2) .encoder-value');
        const totalPulse = this.container.querySelector('.encoder-status .encoder-item:last-child .encoder-value');

        if (leftEncoder && status.left) {
            leftEncoder.textContent = status.left.pulse || 0;
            leftEncoder.classList.toggle('error', !status.left.working);
        }

        if (rightEncoder && status.right) {
            rightEncoder.textContent = status.right.pulse || 0;
            rightEncoder.classList.toggle('error', !status.right.working);
        }

        if (totalPulse) {
            const total = (status.left?.pulse || 0) + (status.right?.pulse || 0);
            totalPulse.textContent = total;
        }
    }

    init() {
        this.renderUI();
        this.bindEvents();
        this.subscribeToStateChanges();

        // 订阅 WebSocket 连接状态
        const ws = window.webSocketHandler;
        if (ws) {
            ws.addEventListener('connectionStatusChange', (status) => {
                this.updateConnectionStatus(status);
            });
        }
    }

    destroy() {
        if (this.stateManager) {
            this.stateManager.removeListener(this.updateUI.bind(this));
        }
        if (this.container) {
            this.container.innerHTML = '';
        }
    }
}

// 导出到全局作用域
if (typeof window !== 'undefined') {
    window.RobotMotionPanel = RobotMotionPanel;
}

// CommonJS 模块导出
if (typeof module !== 'undefined' && module.exports) {
    module.exports = {
        RobotMotionPanel
    };
}
